﻿using CommunityToolkit.Mvvm.ComponentModel;
using CommunityToolkit.Mvvm.Input;
using CommunityToolkit.Mvvm.Messaging;
using Enterprises.Wpf.Sample.Data;
using Enterprises.Wpf.Sample.Data.Model;
using Enterprises.Wpf.Sample.Messages;
using Enterprises.Wpf.Sample.Services;
using Enterprises.Wpf.Sample.Tools.Helper;
using Enterprises.Wpf.Sample.UserControls;
using HandyControl.Controls;
using HandyControl.Properties.Langs;
using System.Collections.ObjectModel;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Threading;
using Enterprises.Wpf.Core.Logs;
using NLog;

namespace Enterprises.Wpf.Sample.ViewModel.Main
{
    public partial class MainViewModel : ObservableRecipient
    {
        [ObservableProperty]
        private object _contentTitle;

        [ObservableProperty]
        private object _subContent;

        [ObservableProperty]
        private bool _isCodeOpened;

        /// <summary>
        /// 左侧菜单组名称,默认HandyControl.json 数据源
        /// </summary>
        [ObservableProperty]
        private string _leftMenuGroupName= "HandyControl";

        /// <summary>
        /// 数据列表
        /// </summary>
        [ObservableProperty]
        private IList<DemoDataModel> _dataList;

        private readonly DataService _dataService;
        private readonly ILogger _log;

        public MainViewModel(DataService dataService, ILogger log)
        {
            _dataService = dataService;
            _log = log;

            UpdateMainContent();
            UpdateLeftContent();
        }

        public DemoItemModel DemoItemCurrent { get; private set; }

        public DemoInfoModel DemoInfoCurrent { get; set; }

        /// <summary>
        /// 左侧菜单
        /// </summary>

        [ObservableProperty]
        public ObservableCollection<DemoInfoModel> demoInfoCollection;

        /// <summary>
        /// 左侧菜单选择变化事件，即点击菜单事件
        /// </summary>
        public RelayCommand<SelectionChangedEventArgs> SwitchDemoCmd => new(SwitchDemo);

        /// <summary>
        /// 隐藏显示菜单
        /// </summary>
        public RelayCommand OpenPracticalDemoCmd => new(OpenPracticalDemo);

        public RelayCommand GlobalShortcutInfoCmd => new(() => Growl.Info("Global Shortcut Info"));

        public RelayCommand GlobalShortcutWarningCmd => new(() => Growl.Warning("Global Shortcut Warning"));

        public RelayCommand OpenDocCmd => new(() =>
        {
            
        });

        public RelayCommand OpenCodeCmd => new(() =>
        {
            if (DemoItemCurrent is null)
            {
                return;
            }

            IsCodeOpened = !IsCodeOpened;
        });

        /// <summary>
        /// 主页面加载事件
        /// </summary>
        private void UpdateMainContent()
        {
            WeakReferenceMessenger.Default.Register<object, string>(this, MessageToken.LoadShowContent, (o, m) =>
            {
                if (SubContent is IDisposable disposable)
                {
                    disposable.Dispose();
                }

                SubContent = m;
            });
        }

        /// <summary>
        /// 加载菜单
        /// </summary>
        private void UpdateLeftContent()
        {
            // 注册左侧菜单事件，包括菜单组改变，菜单选择取消等.
            // 注册带token的消息通道.
            Messenger.Register<LeftMenuChangedMessage, string>(this, MessageToken.ClearLeftSelected, (o, m) =>
            {
                DemoItemCurrent = null;

                // 菜单组改变,重新加载左侧菜单
                if (!string.IsNullOrEmpty(m.MenuGroup) && LeftMenuGroupName != m.MenuGroup)
                {
                    LeftMenuGroupName = m.MenuGroup;
                    LoadLeftMenus();
                }

                foreach (var item in DemoInfoCollection)
                {
                    item.SelectedIndex = -1;
                }
            });

            DataList = _dataService.GetDemoDataList();
            // 加载左侧菜单.
            LoadLeftMenus();
        }

        private void LoadLeftMenus()
        {
            DemoInfoCollection = new ObservableCollection<DemoInfoModel>();
            foreach (var item in _dataService.GetLeftMenus(LeftMenuGroupName))
            {
                Application.Current.Dispatcher.BeginInvoke(new Action(() =>
                {
                    DemoInfoCollection.Add(item);
                }), DispatcherPriority.ApplicationIdle);
            }
        }

        /// <summary>
        /// 做出菜单选择事件
        /// </summary>
        /// <param name="e"></param>
        private void SwitchDemo(SelectionChangedEventArgs e)
        {
            if (e.AddedItems.Count == 0) return;
            if (e.AddedItems[0] is DemoItemModel item)
            {
                if (Equals(DemoItemCurrent, item)) return;
                SwitchDemo(item);
            }
        }

        /// <summary>
        /// 菜单事件处理
        /// </summary>
        /// <param name="item"></param>
        private void SwitchDemo(DemoItemModel item)
        {
            DemoItemCurrent = item;
            ContentTitle = LangProvider.GetLang(item.Name);
            var obj = AssemblyHelper.ResolveByKey(item.TargetCtlName);
            var ctl = obj ?? AssemblyHelper.CreateInternalInstance($"UserControls.Controls.{item.TargetCtlName}");
            // 是否全屏展示消息
            WeakReferenceMessenger.Default.Send(new FullSwitchMessage(ctl is IFull), MessageToken.FullSwitch);

            try
            {
                // 加载页面
                WeakReferenceMessenger.Default.Send(ctl, MessageToken.LoadShowContent);
            }
            catch(Exception ex)
            {
                _log.Error(ex,"功能还未实现");
                LogHelper.Error("LogHelper输出功能还未实现",ex);
                Growl.Info($"{ctl}功能暂未实现，后续脑补.");
            }
        }

        /// <summary>
        /// 实用例子点击事件
        /// </summary>
        private void OpenPracticalDemo()
        {
            // 清除菜单选中
            WeakReferenceMessenger.Default.Send<LeftMenuChangedMessage, string>(new LeftMenuChangedMessage(), MessageToken.ClearLeftSelected);

            // 内容全屏，即隐藏菜单
            WeakReferenceMessenger.Default.Send<FullSwitchMessage, string>(new FullSwitchMessage(true), MessageToken.FullSwitch);
        }
    }
}
